#include <boost/lexical_cast.hpp>
#include <boost/thread.hpp>
#include "curl/curl.h"
#include "libgo/coroutine.h"
#include "libzq/net/client_impl.h"
#include "libzq/net/server_impl.h"
#include "libzq/net/msgpack.h"
#include "libzq/service/protocol/jrpc.h"
#include "libzq/service/register.h"
#include "libzq/log/log.h"
#include "libzq/thirdparty/json11/json11.hpp"
#include "libzq/util/utime.h"

int main(int argc, char** argv)
{
	if (argc < 3) {
		printf("Usage %s url concurrency\n", argv[0]);
		exit(1);
	}

	curl_global_init(CURL_GLOBAL_ALL);

	uint16_t port = atoi(argv[1]);
	int client_num = atoi(argv[2]);

	jrpc::HttpFinder::instance().init("http://127.0.0.1:43330/server-finder/");

	go[port]()
	{

		auto server = new jrpc::JsonServer();
		server->init("http://127.0.0.1:43330/server-register/");
		server->install_module("libzq_user", "./libuser.so.1.0");
		server->install_handler("heartbeat", [](const jrpc::JsonProtocol& req)
		{
			auto ret = json11::Json::object{ { "timestamp", int(libzq::current_timestamp()) } };
			return jrpc::JsonProtocol(ret);
		});
		go std::bind(&ServerImpl::start_serve, server, "0.0.0.0", port);
		server->register_to(format("libzq_user@127.0.0.1:%d", port));
	};

	for (int i = 0; i < client_num; i++)
	{
		go[]()
		{
			co_yield;
			while (1)
			{
				auto req = jrpc::JsonRequest::create("libzq_user", "heartbeat");
				auto o = json11::Json::object{ { "__method", "heartbeat" } };
				auto resp = req->retry(3)->expire(3)->exec(o)->await();
				if (resp.is_error())
				{
					int32_t errnono;
					string errmsg;
					std::tie(errnono, errmsg) = resp.error();
					LOGE("Call method %s error %s(%d)", "login", errmsg, errnono);
				}
				else
				{
					LOGT("Get method %s resp %s", "login", resp.dumps());
				}

				co_sleep(1500);
			}
		};

	}

	boost::thread_group tg;
	for (int i = 0; i < 8; ++i)
		tg.create_thread([] {
		co_sched.RunUntilNoTask();
	});
	tg.join_all();

	//co_sched.RunUntilNoTask();
	return 0;
}